#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project ：pyqt5_device 
@File    ：mqtt_client_thread.py
@IDE     ：PyCharm 
@Author  ：Toby
@Date    ：2023/9/15 17:57 
'''

import paho.mqtt.client as mqtt
import json
import time
import logging
from mydb import MySqlDb
from jsonpath import jsonpath
import threading

logger = logging.getLogger(__name__)

def bytetostr(by):
    return str(by, encoding="utf-8")


myset = set()
boxlist=[]

RESPTOPIC='reg-resp'
REQTOPIC='pile-req'


class MqttThread(threading.Thread):

    def __init__(self, content):
        super(MqttThread, self).__init__()

        self.mngid = str.split(content,',')[0]
        self.device_type = str.split(content,',')[1]
        print(f"mngid-->{self.mngid},device_type-->{self.device_type} ")
        self.db = MySqlDb()

    def run(self):
        def on_connect(client, userdata, flags, rc):
            print("Connected with result code " + str(rc) + "\n")
            if rc == 0:
                print("Connected to MQTT OK!, Will Subs message :")
            else:
                print("Failed to connect, return code %d\n", rc)

        def on_message(client, userdata, msg):
            message = msg.payload.decode("utf-8")
            message = json.loads(message)
            alltopic = msg.topic
            mngid = alltopic.split("/", 3)[2]
            topic_name = alltopic.split("/", 3)[3]
            print(f'on_message -->topic: {topic_name},mngid: {mngid},message : {message}\n')

            # Recv Subscribe topic /XLV/4ebdcda13dba/reg-resp,
            # MSG {"msgSN":0,"errorCode":0,"data":{"boxCode":"710252","ps":[0,0,0,0,0,0]},"servertime":1694690353}
            if topic_name == RESPTOPIC:
                # {"ver": "V1.00.17", "model": "XLR_GC20", "signal": -51}
                print(f'注册服务器返回消息接收：{topic_name},message : {message}\n')
                if message['errorCode'] == 0:
                    boxCode = message['data']['boxCode']
                    sql = "select * from t_charge_pile where boxCode=" + '"' + str(boxCode) + '"' + " limit 1;"
                    ress = self.db.select_sql(sql)
                    if ress:
                        mngid = ress[0]['mngId']
                        model = ress[0]['model']
                        if mngid not in myset:
                            myset.add(mngid)
                            # print(f'当前注册成功MNGID：{myset}')
                            logger.info('当前已经启动上线的mngid',myset)
                            data ={"mngid":mngid,"boxcode":str(boxCode)}

                            with open('boxlist.txt','a+',encoding='utf-8') as fp:
                                fp.write(json.dumps(data)+"\n")

                else:
                    print('SQL数据库中没有查询到boxcode 编码!')

            elif topic_name == REQTOPIC:
                port = message['port']
                op = message['op']  # 1下单 0 关单
                dcode = message['dcode']
                global starttime

                if mngid in myset:
                    if op == 1:
                        print(' -----op-----> =1')
                        topic_name = '/CHG/' + mngid + '/pile-resp'
                        payload = {
                            "errorCode": 0,
                            "dcode": dcode
                        }
                        print('publish: topic payload>>>>', payload)
                        self.publish(client=client, payload=payload, topicname=topic_name)
                        time.sleep(1)
                        # Topic /CHG/4ebdcda13dba/chg-paca-rep,# MSG {}
                        topic_name2 = '/CHG/' + mngid + '/chg-paca-rep'
                        # payload2 = {
                        #     "mcode": port,
                        #     "status": "WAIT_CLOSE",
                        #     "cc": 0,
                        #     "extInt": 0,
                        #     "cv": 221723,
                        #     "dcode": dcode,
                        #     "dsc": "NEW_STA",
                        #     "ele": 0
                        # }
                        # print('publish: topic  payload>>>>', payload2)
                        # time.sleep(1)
                        # self.publish(client=client, payload=payload2, topicname=topic_name2)
                        payload3 = {
                            "mcode": port,
                            "status": "WAITING",
                            "cc": 1183,
                            "extInt": 165,
                            "cv": 225756,
                            "dcode": dcode,
                            "dsc": "START",
                            "ele": 0
                        }
                        print('publish: topic  payload>>>>', topic_name2)
                        self.publish(client=client, payload=payload3, topicname=topic_name2)

                        time.sleep(1)
                        topic_power = "/CHG/" + mngid + "/power"
                        # 充电开始时间
                        starttime = int(time.time())
                        payload_power = {
                            "dcode": dcode,
                            "start": starttime,
                            "end": starttime,
                            "power": 165,
                            "index": 1
                        }
                        self.publish(client=client, payload=payload_power, topicname=topic_power)

                        payload_chgfast = {
                            "mcode": 1,
                            "status": "CHG_FAST",
                            "cc": 1183,
                            "extInt": 165,
                            "cv": 225756,
                            "dcode": dcode,
                            "dsc": "NEW_STA",
                            "ele": 0
                        }
                        self.publish(client=client,payload=payload_chgfast, topicname=topic_name2)
                        time.sleep(1)
                        topic_name = "/CHG/" + mngid + "/chg-data-rep"
                        payload_data = {"port": port,
                                        "status": 1,
                                        "ele": 28,
                                        "freeTime": 0,
                                        "freeDegree": 0,
                                        "power": 172,
                                        "invol": 0,
                                        "total": 0,
                                        "errCode": 0,
                                        "msgSN": 21,
                                        "dcode": dcode
                                        }
                        print('publish: topic>>>>', topic_name)

                        self.publish(client=client, payload=payload_data, topicname=topic_name)

                    elif op == 0:  # 关单的情况处理
                        print('op = 0')
                        # {"msgSN":0,"port":5,"op":0,"dcode":"0000000564112275","me":0,
                        # "mt":0,"pt":6000,"se":0,"sd":0,"door":1,"pp":0,
                        # "servertime":1694789227}
                        servertime = message['servertime']
                        time.sleep(1)

                        if self.device_type == '20':
                            print("-----G20-----")
                            topic_power = "/CHG/" + mngid + "/power"
                            payload_power = {
                                "dcode": dcode,
                                "start": int(time.time()),
                                "end": servertime,
                                "power": 168,
                                "index": 1
                            }
                            self.publish(client=client, payload=payload_power, topicname=topic_power)
                            time.sleep(1)

                            topic_name = '/CHG/' + mngid + '/chg-paca-rep'
                            payload = {"mcode": port,
                                       "status": "CHG_FAST",
                                       "cc": 1251,
                                       "extInt": 172,
                                       "cv": 225200,
                                       "dcode": dcode,
                                       "dsc": "TERM_EX",
                                       "ele": 0  # 电量 degree
                                       }

                            self.publish(client=client, payload=payload, topicname=topic_name)

                            topic_name = '/CHG/' + mngid + '/pile-resp'
                            payload = {
                                "errorCode": 0,
                                "dcode": dcode
                            }
                            self.publish(client=client, payload=payload, topicname=topic_name)

                            topic_name = '/CHG/' + mngid + '/chg-data-rep'
                            payload = {
                                "port": port,
                                "status": 6,
                                "ele": 70,
                                "freeTime": 0,
                                "freeDegree": 0,
                                "power": 160,
                                "invol": 1481,
                                "total": 1481,
                                "errCode": 36,
                                "msgSN": 134,
                                "dcode": dcode
                            }

                            self.publish(client=client, payload=payload, topicname=topic_name)
                        elif self.device_type == '31' or self.device_type=='50':
                            print("-----C31-----C50")
                            # self.device_status.upmessage.emit(ress_list)
                            sql = "select * from t_charge_pile where mngId=" + '"' + str(mngid) + '"' + " limit 1;"
                            ress = self.db.select_sql(sql)
                            boxcode = ress[0]['boxCode']

                            topic_power = "/CHG/" + mngid + "/power"
                            payload_power = {
                                "dcode": dcode,
                                "start": servertime,
                                "end":  int(time.time()),
                                "power": 168,
                                "index": 1
                            }
                            self.publish(client=client, payload=payload_power, topicname=topic_power)

                            topic_name = "/CHG/" + mngid + "/chg-paca-rep"
                            payload = {
                                "mcode": str(boxcode) + str(port),
                                "status": "CHG_FAST",
                                "cc": 1440,
                                "extInt": 190,
                                "cv": 214657,
                                "dcode": dcode,
                                "dsc": "",
                                "ele": 34,
                                "temp": 0}
                            # 插排发送关单的消息 payload2
                            self.publish(client=client, payload=payload, topicname=topic_name)

                            topic_name = '/CHG/' + mngid + '/pile-resp'
                            payload = {
                                "errorCode": 0,
                                "dcode": dcode
                            }
                            self.publish(client=client, payload=payload, topicname=topic_name)

                            topic_name = '/CHG/' + mngid + '/chg-data-rep'
                            payload = {
                                "port": port,
                                "status": 2,
                                "ele": 34,
                                "freeTime": 0,
                                "freeDegree": 0,
                                "power": 200,
                                "invol": 1481,
                                "total": 0,
                                "errCode": 36,
                                "msgSN": 134,
                                "dcode": dcode
                            }

                            self.publish(client=client, payload=payload, topicname=topic_name)

                            topic_name = "/CHG/" + mngid + "/chg-paca-rep"
                            payload = {
                                "mcode": str(boxcode) + str(port),
                                "status": "IDLE",
                                "cc": 5,
                                "extInt": 0,
                                "cv": 214657,
                                "dcode": "",
                                "dsc": "",
                                "ele": 0,
                                "temp": 0}
                            # 插排发送关单的消息 payload2
                            self.publish(client=client, payload=payload, topicname=topic_name)


                else:
                    print('mngid 不在set 中')

        def on_subscribe(client, userdata, mid, granted_qos):
            print('----on_subscribe-------')
            print(client, userdata, mid, granted_qos)

        def on_publish_callback(client, userdata, mid):
            print('----on_publish_callback-------')
            print(client, userdata, mid)

        def subMessage(client):
            # 订阅消息
            client.subscribe("/CHG/" + bytetostr(client._client_id) + "/reg-req")
            client.subscribe("/XLV/" + bytetostr(client._client_id) + "/pile-req")
            client.subscribe("/XLV/" + bytetostr(client._client_id) + "/reg-resq")
            client.subscribe("/XLV/" + bytetostr(client._client_id) + "/chg-data-resp")
            client.subscribe("/XLV/" + bytetostr(client._client_id) + "/syscfg")
            client.subscribe("/XLV/" + bytetostr(client._client_id) + "/reg-resp")

        self.client = mqtt.Client(self.mngid)
        print("当前客户端 MQTT ID:{}\n".format(bytetostr(self.client._client_id)))
        self.client.on_connect = on_connect
        self.client.on_message = on_message
        self.client.on_subscribe = on_subscribe
        self.client.on_publish = on_publish_callback

        with open('./config.json', 'r', encoding='utf-8')as fp:
            json_data = fp.read()
            json_data = json.loads(json_data)
            self.SERVER_HOST = jsonpath(json_data, "$.testsss.mqttbroker.SERVER_HOST")
            self.USER_NAME = jsonpath(json_data, "$.testsss.mqttbroker.USER_NAME")
            self.PASSWORD = jsonpath(json_data, "$.testsss.mqttbroker.PASSWORD")
            self.BIND_PORT = jsonpath(json_data, "$.testsss.mqttbroker.BIND_PORT")

        self.client.username_pw_set(self.USER_NAME[0], self.PASSWORD[0])
        self.client.connect(self.SERVER_HOST[0], self.BIND_PORT[0], 60)

        subMessage(self.client)

        # 柜和插排注册
        topic = "/CHG/" + bytetostr(self.client._client_id) + "/reg-req"

        # 柜 插座柜  device_type 用来指定model类型 633907  710252
        if self.device_type == '20':
            payload = {"ver": "V1.00.17", "model": "XLR_GC20", "signal": -51}
            self.publish(self.client, topicname=topic, payload=payload)
            print(f" MQTT  注册消息，register topic:{topic},payload :{payload}")

        # 插排 31  device_type 300896
        elif self.device_type == '31':
            print(f"device_type :‘{self.device_type}’")  # 300896  XLR_C50
            payload = {'ver': 'V1.00.25', 'model': 'XLR_C31', 'signal': 26}
            self.publish(self.client, topicname=topic, payload=payload)
            print(f" MQTT  注册消息，register topic:{topic},payload :{payload}")


        elif self.device_type == '50':
            print(f"device_type :‘{self.device_type}’")
            payload = {'ver': 'V1.00.05', 'model': 'XLR_C50', 'signal': 26}
            self.publish(self.client, topicname=topic, payload=payload)
            print(f" MQTT  注册消息，register topic:{topic},payload :{payload}")


        self.client.loop_forever()

    def publish(self, client, topicname, payload):
        print(f'client will  publish payload: {payload}')
        json_payload = json.dumps(payload)
        info = client.publish(topicname, json_payload, qos=1)
        mid = info.mid
        print(f"client published mid-->{mid} :payload:{payload} ,publish over")


if __name__ == '__main__':
    line = "4eabd419b064,20"
    client_thread = MqttThread(line)
    client_thread.start()
